PIC入出力ポートの誤動作実験
注意事項!!
本実験は、PICの入出力ポートに過大な負担がかかります。
場合によっては入出力ポートが壊れることがあります。
実験を試みる方は、個人の責任で行ってください。
実験により、いかなる損害が発生しても、当方ならびに実験に関わった
情報提供者は一切の責任を負いません。あらかじめご承知ください。
たわごとのページ#70にて、PIC入出力ポートの誤動作防止についてのご意見を高山さんから頂いてから、この件に関する内容に興味を持ち始めました。PIC入出力ポートの誤動作とは、Microchip社のデータシート(たとえば、PIC16F8XではP.25
I/O プログラミングの注意点)や、PIC活用ガイドブックのP.75,76と、P131に入出力ポートの誤動作に関する件がありますので、それを見ると原理的なことは理解できると思います。実際に入出力ポートの誤動作対策が必要になるような負荷容量の高い環境でPICを使った経験が無いので、今回、容量負荷をつないで誤動作を起こした実験をしてみようかと考えています。
ハード側の接続
図1にPIC入出力ポートの誤動作の実験回路を示します。PICは16F877を使用し、PORTBの端子のレベル状態が分かるようにLEDを接続します。ただし、ポートに直接LEDを接続してしまうと端子に負荷がかかるので、バッファを介して接続するようにします。誤作動の観測対象ピンとしてPORTBの端子に容量負荷を接続します。(図1は、RB3に容量負荷を接続した例です)。MCLR端子はリセット用に回路を設けておきますが、なくても構いません。PICのクロック周波数は、20MHzです。
![]() |
図1.PIC入出力ポートの誤動作の実験回路 |
実験手順
図1のPIC入出力ポートの誤動作の実験回路にて、「C」のところ(RB3端子とGND間)にコンデンサを接続していきますが、作業がカット&トライになるので、図2のようにブレッドボードを用いた方が楽です。コンデンサは容量値の正確さと安定性を考慮してマイカ・コンデンサを選定しました。なければ安価なセラミックコンデンサでも構いません。容量値は、数pF〜数100pF程度の範囲で何種類か用意し、容量が足りなければ並列に接続するようにします。プログラムは誤動作の再現性を確認できるように一連の動作が繰り返されいるので、コンデンサの容量値を変えながら随時確認することができます。
![]() |
図2.入出力ポートに接続するコンデンサ |
誤動作確認のプログラム(1-1)
信号レベル H→ Lの動作チェック
図3にPIC入出力ポートの誤動作確認プログラム(1-1)として、信号レベルH→Lの動作チェックを確認するプログラムのフローチャートを示します。
プログラムの解説については、「プログラムの説明」の項をご参照ください。
![]() ![]() |
図3.PIC入出力ポートの誤動作確認 プログラム(1-1)のフローチャート (信号レベルは、 H→L 動作) |
(注)以下に示すプログラムには、ホームページ画面作成の都合上、空白として全角文字のスペースなどが挿入されています。したがって、下記プログラムリストをそのままコピーしてMPLABのソースファイルとされた場合には、エラーとなることがあります。
→ここをクリックして、下記のプログラムをダウンロードするようにしてください。
ファイル名:「pic_11.asm」 サイズ3.06kバイト
→ここをクリックして、下記のオブジェクトファイルをダウンロードするようにしてください。
ファイル名:「pic_11.hex」 サイズ300バイト
;*********************************************************** ; ; PIC入出力ポート誤動作テストプログラム(1-1) ; 信号レベル H→L の動作チェック ; ;*********************************************************** |
|
LIST P=PIC16F877 INCLUDE P16F877.INC |
;(1)プロセッサの種別指定 ;(2)インクルードファイルの指定 |
;*********************************************************** ; 変数定義とレジスタ割付 ;*********************************************************** |
|
COUNT EQU 20H COUNT1 EQU 21H COUNT2 EQU 22H COUNT3 EQU 23H COUNT4 EQU 24H ORG 0 |
;(3)ループカウンタ ; ループカウンタ1 ; ループカウンタ2 ; ループカウンタ3 ; ループカウンタ4 ;(4)プログラムの開始番地の指定 |
;*********************************************************** ; 入出力ピン初期化 ;*********************************************************** |
|
BSF STATUS,RP0 CLRF TRISB BCF STATUS,RP0 |
;(5)Bank 1 へ切替 ;(6)PortB を設定(全ピン出力) ;(7)Bank 0 へ戻す |
;*********************************************************** ; メインプログラム ;*********************************************************** |
|
MAIN MOVLW 0FFH MOVWF PORTB CALL TIME1S BCF PORTB,7 BCF PORTB,6 BCF PORTB,5 BCF PORTB,4 BCF PORTB,3 BCF PORTB,2 BCF PORTB,1 BCF PORTB,0 CALL TIME1S CALL TIME1S CALL TIME1S GOTO MAIN |
; ;(8)全ピンHレベルに設定 ; ポートBへ出力 ;(9)1秒間のウェイト ;(10)RB7ピンをLレベルに設定 ; RB6ピンをLレベルに設定 ; RB5ピンをLレベルに設定 ; RB4ピンをLレベルに設定 ; RB3ピンをLレベルに設定 ; RB2ピンをLレベルに設定 ; RB1ピンをLレベルに設定 ; RB0ピンをLレベルに設定 ;(11)1秒×3=3秒のウエイト ; ; ;(12)繰り返し(MAINラベルへ戻る) |
;*********************************************************** ;遅延サブルーチン ;*********************************************************** ;100?s遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ ; ;10ms遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ ; ;1s遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ |
|
END |
【プログラムの説明(1-1)】
このプログラムについて、順を追って解説を加えておきましょう。
(1)プロセッサの種別指定
定義の仕方は「PROCESSOR」か「LIST」命令を使って設定します。ここで指定するプロセッサ名称は、パッケージの種類を示すサフィックス(最後の英記号の部分)は不要です。
PROCESSOR PIC16F877
または
LIST P=PIC16F877
(2)標準ヘッダーファイルのインクルード
標準ヘッダーファイルとは、各プロセッサが持っているSFR(Special
Function Register)をラベル(記号)で使えるため、ラベルとハードウェアの場所とを定義しているファイルです。標準ヘッダーファイルは 「プロセッサ名.INC」というファイル名で統一されて、MPLABのディレクトリに格納されています。従って、これのインクルード方法は下記のようにして行います。
一度、参考までに標準ヘッダーファイルの内容をエディタ等で見ておくことをお勧めします。
INCLUDE P16F877.INC
または
#INCLUDE P16F877.INC
(3)変数定義とレジスタ割付
レジスタファイルアドレスを指定するときに、アドレス数値を直接指定することもできますが、数値だけでは間違いも多く、プログラム自身も分かりにくくなってしまいます。そこで、EQU命令などを使ってラベルを設定し変数を定義します。レジスタファイルアドレスは、7ビットあるので、00〜7Fまで最大128個のレジスタが指定できますが、実際に物理的に実装されて汎用的に使用できるレジスタ数はデバイスによって異なっていますので注意が必要です。
PIC16F877の汎用レジスタのアドレスは、20H〜7FH
となっていますので、20H以降のアドレスに割り付けます。
(4)プログラムの開始番地の指定
「ORG」はプログラムの開始番地を指定する擬似命令で、ORG以下の実際のプログラム命令が格納されるプログラムメモリ内の位置(アドレス)を指定します。
ORG 0 ;0番地から格納することを示します。
コンピュータは一般に電源投入時やリセットをすると必ず0番地からスタートするようになっているので、0番地には必ず命令があることが必要です。
(5)Bank 1 へ切替
PICには各種の動作モードを設定するための Special
Register と呼ばれるものが用意されています。PICを動作させるためには、まずこのSpecial
Registerの設定から始めます。そしてそれらは全て、Register
File と呼ぶメモリとして用意されています。その
Register Fileは Bank0, Bank1, Bank2, Bank3
とよばれるアドレス空間をもっているため、多少アクセスの仕方が面倒です。つまりRESET後の通常はBank0となっているので、Bank1側のレジスタにアクセスするときはBankの切替えをしてからとなります。またBank0とBank1に同じ物があるときにはどちらでも同じ様に使えます。
Bank1へ切り替える方法ですが、「STATUS」レジスタにある2ビットのRP0、RP1を変えてBankを指定します。デフォルトは、Bank0です。表1にBankとRP1,RP0ビットとの関係を示します。Bank1へ切り替えるためには、RP0ビットを「1」にします。(RP1はデフォルトで「0」なので変える必要はない。)
BSF STATUS,RP0
「STATUS」レジスタのRP0ビットを「1」にする。
Bank | RP1 | RP0 |
0 | 0 | 0 |
1 | 0 | 1 |
2 | 1 | 0 |
3 | 1 | 1 |
(6)PORTB 全ポートを出力に設定
TRISBレジスタを、CLRF(fレジスタをゼロクリアする命令)で出力設定とします。
CLRF TRISB
「TRISBレジスタをゼロクリアする。すなわち、PORTB全ポートを出力に設定する」
(7)Bank 0 へ戻す
Bank1での設定が終了した後は、Bank0に戻しておきます。Bank1へ切り替えるためには、RP0ビットを「0」にします。(RP1はデフォルトで「0」なので変える必要はない。)
BCF STATUS,RP0
「STATUS」レジスタのRP0ビットを「0」にする。すなわち、Bank0に戻す。」
(8)全ピンHレベルに設定
ポートBへ出力
はじめに全ビットをMOVWFの転送命令で「High」に出力しておきます。
(9)1秒間のウェイト
LEDの点滅の様子が、人間の目で分かるように1秒間のウエイトを入れました。
TIME1Sというラベルの付いたサブルーチンへジャンプします。
このとき、LEDは全部点灯しています。
(10)RB7〜0ピンを順次Lレベルに設定
BCF命令により、RB7からRB0までの端子を順次Lレベルに設定していきます。
(11)1秒×3=3秒のウエイト
BCF命令の実行後に、ポートBの全ビットがLレベルになっていること(LEDが消灯していること)を確認するため、3秒間のウエイトを挿入します。もし、ここで入出力ポートの誤動作が発生した場合には、LEDが点灯したままになります。
(12)繰り返し(MAINラベルへ戻る)
これまでの動作を繰り返して、誤動作の再現性を確認します。
実験結果(1-1)
信号レベル H→ Lの動作チェック
図4に正常動作時と異常動作時の様子を写真撮影しました。LEDは端子のレベルがHレベルの時に発光するようになっています。図4の上段は、プログラム(9)の段階で、まずは全端子をHレベルにします。下段は、プログラム(11)の段階です。正常動作の場合(左)は、全端子はBCF命令によりLレベルになっていることが分かります。ところが、RB3端子に容量負荷があると、右下の写真のように容量負荷のある端子のLEDが点灯したままになってしまいました。すなわち、本来プログラム上ではLレベルに設定されるはずが、容量負荷の影響で誤動作を引き起こすことが確認されました。
![]() |
![]() |
↓正常な場合 | ↓誤動作した場合 |
![]() |
![]() |
(左)正常動作時: 全端子Lレベル |
(右)異常動作時: RB3端子がHレベル |
図4.PIC入出力ポートの様子 (信号レベル H→ Lの動作チェック) |
誤動作を引き起こしたときの条件ですが、C=370〜380pF以上のコンデンサで発生しました。なお、電解コンデンサのようなμF単位の容量の大きなコンデンサは、端子のレベル変化時に過大な電流が流れるため、PICのポートを痛める可能性があります。そのため確認実験は0.1μFの積層セラミックコンデンサまでとしました。
(注)ポートBはPIC内部に50kΩ程度のプルアップ抵抗(Weak
pull-up)が内蔵されていますが、初期設定ではプルアップしないになっています。OPTION_REGレジスタの7ビットを「0」にすることでプルアップ使用に設定できます。
誤動作確認のプログラム(1-2)
信号レベル L→ Hの動作チェック
図5にPIC入出力ポートの誤動作確認プログラム(1-2)として、信号レベルL→Hの動作チェックを確認するプログラムのフローチャートを示します。
![]() ![]() |
図5.PIC入出力ポートの誤動作確認 プログラム(1-2)のフローチャート (信号レベルは、 L→H 動作) |
(注)以下に示すプログラムには、ホームページ画面作成の都合上、空白として全角文字のスペースなどが挿入されています。したがって、下記プログラムリストをそのままコピーしてMPLABのソースファイルとされた場合には、エラーとなることがあります。
→ここをクリックして、下記のプログラムをダウンロードするようにしてください。
ファイル名:「pic_12.asm」 サイズ3.07kバイト
→ここをクリックして、下記のオブジェクトファイルをダウンロードするようにしてください。
ファイル名:「pic_12.hex」 サイズ300バイト
;*********************************************************** ; ; PIC入出力ポート誤動作テストプログラム(1-2) ; 信号レベル L→H の動作チェック ; ;*********************************************************** |
|
LIST P=PIC16F877 INCLUDE P16F877.INC |
;(1)プロセッサの種別指定 ;(2)インクルードファイルの指定 |
;*********************************************************** ; 変数定義とレジスタ割付 ;*********************************************************** |
|
COUNT EQU 20H COUNT1 EQU 21H COUNT2 EQU 22H COUNT3 EQU 23H COUNT4 EQU 24H ORG 0 |
;(3)ループカウンタ ; ループカウンタ1 ; ループカウンタ2 ; ループカウンタ3 ; ループカウンタ4 ;(4)プログラムの開始番地の指定 |
;*********************************************************** ; 入出力ピン初期化 ;*********************************************************** |
|
BSF STATUS,RP0 CLRF TRISB BCF STATUS,RP0 |
;(5)Bank 1 へ切替 ;(6)PortB を設定(全ピン出力) ;(7)Bank 0 へ戻す |
;*********************************************************** ; メインプログラム ;*********************************************************** |
|
MAIN MOVLW 0H MOVWF PORTB CALL TIME1S BSF PORTB,7 BSF PORTB,6 BSF PORTB,5 BSF PORTB,4 BSF PORTB,3 BSF PORTB,2 BSF PORTB,1 BSF PORTB,0 CALL TIME1S CALL TIME1S CALL TIME1S GOTO MAIN |
; ;(8)全ピンLレベルに設定 ; ポートBへ出力 ;(9)1秒間のウェイト ;(10)RB7ピンをHレベルに設定 ; RB6ピンをHレベルに設定 ; RB5ピンをHレベルに設定 ; RB4ピンをHレベルに設定 ; RB3ピンをHレベルに設定 ; RB2ピンをHレベルに設定 ; RB1ピンをHレベルに設定 ; RB0ピンをHレベルに設定 ;(11)1秒×3=3秒のウエイト ; ; ;(12)繰り返し(MAINラベルへ戻る) |
;*********************************************************** ;遅延サブルーチン ;*********************************************************** ;100?s遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ ; ;10ms遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ ; ;1s遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ |
|
END |
【プログラムの説明(1-2)】
プログラムの説明(1-1)と重複するところは省略します。プログラム(1-1)との変更点は次のところです。
(8)全ピンLレベルに設定
ポートBへ出力
はじめに全ビットをMOVWFの転送命令で「Low」に出力しておきます。
(10)RB7〜0ピンを順次Hレベルに設定
BSF命令により、RB7からRB0までの端子を順次Hレベルに設定していきます。
実験結果(1-2)
信号レベル L→ Hの動作チェック
図6に正常動作時と異常動作時の様子を写真撮影しました。LEDは端子のレベルがHレベルの時に発光するようになっています。図6の上段は、プログラム(9)の段階で、まずは全端子をLレベルにします。下段は、プログラム(11)の段階です。正常動作の場合(左)は、全端子はBSF命令によりHレベルになっていることが分かります。ところが、RB3端子に容量負荷があると、右下の写真のように容量負荷のある端子のLEDは点灯しませんでした。すなわち、本来プログラム上ではHレベルに設定されるはずが、容量負荷の影響で誤動作を引き起こすことが確認されました。誤動作を引き起こしたときの条件ですが、信号レベル
L→ Hの動作の場合、C=750pF以上のコンデンサで発生しました。先ほどの信号レベル
H→ Lの動作の場合では、C=370〜380pF以上でした。
![]() |
![]() |
↓正常な場合 | ↓誤動作した場合 |
![]() |
![]() |
(左)正常動作時: 全端子Hレベル |
(右)異常動作時: RB3端子がLレベル |
図6.PIC入出力ポートの様子 (信号レベル L→ Hの動作チェック) |
誤動作確認のプログラム(2-1)
NOP命令を挿入した場合
信号レベル H→ Lの動作チェック
BCF/BSF命令で設定した後にNOP命令を挿入しました。誤動作防止にどの程度効果があるのか下記のプログラムで調べてみます。
→ここをクリックして、下記のプログラムをダウンロードするようにしてください。
ファイル名:「pic_21.asm」 サイズ3.33kバイト
→ここをクリックして、下記のオブジェクトファイルをダウンロードするようにしてください。
ファイル名:「pic_21.hex」 サイズ345バイト
;*********************************************************** ; ; PIC入出力ポート誤動作テストプログラム(2-1) ; NOP 命令を挿入した場合 ; 信号レベル H→L の動作チェック ; ;*********************************************************** |
|
LIST P=PIC16F877 INCLUDE P16F877.INC |
;(1)プロセッサの種別指定 ;(2)インクルードファイルの指定 |
;*********************************************************** ; 変数定義とレジスタ割付 ;*********************************************************** |
|
COUNT EQU 20H COUNT1 EQU 21H COUNT2 EQU 22H COUNT3 EQU 23H COUNT4 EQU 24H ORG 0 |
;(3)ループカウンタ ; ループカウンタ1 ; ループカウンタ2 ; ループカウンタ3 ; ループカウンタ4 ;(4)プログラムの開始番地の指定 |
;*********************************************************** ; 入出力ピン初期化 ;*********************************************************** |
|
BSF STATUS,RP0 CLRF TRISB BCF STATUS,RP0 |
;(5)Bank 1 へ切替 ;(6)PortB を設定(全ピン出力) ;(7)Bank 0 へ戻す |
;*********************************************************** ; メインプログラム ;*********************************************************** |
|
MAIN MOVLW 0FFH MOVWF PORTB CALL TIME1S BCF PORTB,7 NOP BCF PORTB,6 NOP BCF PORTB,5 NOP BCF PORTB,4 NOP BCF PORTB,3 NOP BCF PORTB,2 NOP BCF PORTB,1 NOP BCF PORTB,0 NOP CALL TIME1S CALL TIME1S CALL TIME1S GOTO MAIN |
; ;(8)全ピンHレベルに設定 ; ポートBへ出力 ;(9)1秒間のウェイト ;(10')RB7ピンをLレベルに設定 ; 誤動作防止のNOP命令 ; RB6ピンをLレベルに設定 ; 誤動作防止のNOP命令 ; RB5ピンをLレベルに設定 ; 誤動作防止のNOP命令 ; RB4ピンをLレベルに設定 ; 誤動作防止のNOP命令 ; RB3ピンをLレベルに設定 ; 誤動作防止のNOP命令 ; RB2ピンをLレベルに設定 ; 誤動作防止のNOP命令 ; RB1ピンをLレベルに設定 ; 誤動作防止のNOP命令 ; RB0ピンをLレベルに設定 ; 誤動作防止のNOP命令 ;(11)1秒×3=3秒のウエイト ; ; ;(12)繰り返し(MAINラベルへ戻る) |
;*********************************************************** ;遅延サブルーチン ;*********************************************************** ;100?s遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ ; ;10ms遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ ; ;1s遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ |
|
END |
【プログラムの説明(2-1)】
プログラムの説明(1-1)と重複するところは省略します。プログラム(1-1)との変更点は次のところです。
(10’)RB7〜0ピンを順次Lレベルに設定
誤動作防止のNOP命令
BCF命令&NOP命令により、RB7からRB0までの端子を順次Lレベルに設定していきます。
実験結果(2-1)
NOP命令を挿入した場合
信号レベル H→ Lの動作チェック
NOP命令がなかった場合は、C=370〜380pFのコンデンサで発生していましたが、BCF命令の後に誤動作防止のNOP命令1個を追加したプログラムでは、C=3300pF程度まで誤動作は生じませんでした。単純計算では、1クロック分相当で誤動作が発生したとすると、NOP命令(4クロック分)を追加した場合は、1+4=5クロック分相当になるので5倍の容量まで大丈夫と推測しましたが、実際には9倍の容量までOKなようです。
誤動作確認のプログラム(2-2)
NOP命令を挿入した場合
信号レベル L→ Hの動作チェック
BCF/BSF命令で設定した後にNOP命令を挿入しました。誤動作防止にどの程度効果があるのか下記のプログラムで調べてみます。
→ここをクリックして、下記のプログラムをダウンロードするようにしてください。
ファイル名:「pic_22.asm」 サイズ3.33kバイト
→ここをクリックして、下記のオブジェクトファイルをダウンロードするようにしてください。
ファイル名:「pic_22.hex」 サイズ345バイト
;*********************************************************** ; ; PIC入出力ポート誤動作テストプログラム(2-2) ; NOP 命令を挿入した場合 ; 信号レベル L→H の動作チェック ; ;*********************************************************** |
|
LIST P=PIC16F877 INCLUDE P16F877.INC |
;(1)プロセッサの種別指定 ;(2)インクルードファイルの指定 |
;*********************************************************** ; 変数定義とレジスタ割付 ;*********************************************************** |
|
COUNT EQU 20H COUNT1 EQU 21H COUNT2 EQU 22H COUNT3 EQU 23H COUNT4 EQU 24H ORG 0 |
;(3)ループカウンタ ; ループカウンタ1 ; ループカウンタ2 ; ループカウンタ3 ; ループカウンタ4 ;(4)プログラムの開始番地の指定 |
;*********************************************************** ; 入出力ピン初期化 ;*********************************************************** |
|
BSF STATUS,RP0 CLRF TRISB BCF STATUS,RP0 |
;(5)Bank 1 へ切替 ;(6)PortB を設定(全ピン出力) ;(7)Bank 0 へ戻す |
;*********************************************************** ; メインプログラム ;*********************************************************** |
|
MAIN MOVLW 0H MOVWF PORTB CALL TIME1S BSF PORTB,7 NOP BSF PORTB,6 NOP BSF PORTB,5 NOP BSF PORTB,4 NOP BSF PORTB,3 NOP BSF PORTB,2 NOP BSF PORTB,1 NOP BSF PORTB,0 NOP CALL TIME1S CALL TIME1S CALL TIME1S GOTO MAIN |
; ;(8)全ピンLレベルに設定 ; ポートBへ出力 ;(9)1秒間のウェイト ;(10')RB7ピンをHレベルに設定 ; 誤動作防止のNOP命令 ; RB6ピンをHレベルに設定 ; 誤動作防止のNOP命令 ; RB5ピンをHレベルに設定 ; 誤動作防止のNOP命令 ; RB4ピンをHレベルに設定 ; 誤動作防止のNOP命令 ; RB3ピンをHレベルに設定 ; 誤動作防止のNOP命令 ; RB2ピンをHレベルに設定 ; 誤動作防止のNOP命令 ; RB1ピンをHレベルに設定 ; 誤動作防止のNOP命令 ; RB0ピンをHレベルに設定 ; 誤動作防止のNOP命令 ;(11)1秒×3=3秒のウエイト ; ; ;(12)繰り返し(MAINラベルへ戻る) |
;*********************************************************** ;遅延サブルーチン ;*********************************************************** ;100?s遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ ; ;10ms遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ ; ;1s遅延サブルーチン(20MHzクロック時) ;・・・・・ 別記プログラムリスト参照・・・・・ |
|
END |
【プログラムの説明(2-2)】
プログラムの説明(1-2)と重複するところは省略します。プログラム(1-2)との変更点は次のところです。
(10’)RB7〜0ピンを順次Hレベルに設定
誤動作防止のNOP命令
BSF命令&NOP命令により、RB7からRB0までの端子を順次Hレベルに設定していきます。
実験結果(2-2)
NOP命令を挿入した場合
信号レベル L→ Hの動作チェック
NOP命令がなかった場合は、C=750pF以上のコンデンサで発生していましたが、BCF命令の後に誤動作防止のNOP命令1個を追加したプログラムでは、C=4700pF程度まで誤動作は生じませんでした。単純計算では、1クロック分相当で誤動作が発生したとすると、NOP命令(4クロック分)を追加した場合は、1+4=5クロック分相当になるので5倍の容量まで大丈夫と推測しましたが、実際には6倍の容量までOKなようです。
まとめ
対象ピンの 信号レベル |
NOP命令なし | NOP命令あり |
H→L | 370 〜380pF以上 |
3300pF 以上 |
L→H | 750pF 以上 |
4700pF 以上 |
使用PIC:PIC16F877-20/P
PORTB 3ピンとGND間にコンデンサを接続
Weak pull-upはオフ
高山さんからの実験報告の紹介
今回の実験におきまして、高山さんから追試の実験報告をいただきましたのでご紹介します。
どもども。。。
高山です。
こちらでも、PORTに対するBCF/BSFでの
データ化けについて、追試してみました。
チップが違うせいか、島田さんの結果よりおおきな容量まで
OKなようです。
●使用PIC
16F876-20/SP
0042GH2
●実験方法
20MHzのセラミックレゾネータで動作。
PORTB1とGNDの間にコンデンサを接続。
以下のプログラムを動作させオシロで波形観測。
Weak pull-upはオフです。
信号0→1のチェック
main
movlw 0x00
movwf PORTB
nop
bsf PORTB,0
bsf PORTB,1 ; 観測対象ポートの操作
bsf PORTB,2 ; 誤動作誘因命令
nop
nop
goto main
信号1→0のチェック
main2
movlw 0xff
movwf PORTB
nop
bcf PORTB,0
bcf PORTB,1 ; 観測対象ポートの操作
bcf PORTB,2 ; 誤動作誘因命令
nop
nop
goto main2
●波形
信号0→1のチェック
負荷無しの状態の波形(図7)
オーバシュート、アンダーシュートが結構出ていますが、適当に作った
実験回路ですので、こんな物でしょう。
横軸は0.1us/DIV、縦軸は2V/DIVになっています。
(横軸は2clock/DIVになります。)
上がPORTB0、下がPORTB1です。
(注)下記の図7〜図11に掲載した写真は、
高山さんが撮影されたものです。
![]() |
図7.信号0→1のチェック 負荷無しの状態の波形 |
容量負荷470+220pfの波形(図8)
セラミックCを並列接続した物です。
立ち上がりの波形が鈍ってきています。
![]() |
図8.信号0→1のチェック 容量負荷470+220pfの波形 |
容量負荷470+330pfの波形(図9)
1クロック後のサンプル時点(信号の立ち上がりから目盛り半分の所)での
電圧がしきい値を下回ってしまっているため、2目盛り先のBSF
PORTB,2の
結果が書き込まれる所で、出力が0に書き換えられてしまっています。
![]() |
図9.信号0→1のチェック 容量負荷470+330pfの波形 |
信号1→0のチェック
容量負荷470+220pfの波形(図10)
0→1ではOKだった同じ容量でも、1→0の場合はこうなりました。
見た感じでは、0.75Vより下まで下がっていそうなんだけど。。。
![]() |
図10.信号1→0のチェック 容量負荷470+220pfの波形 |
容量負荷470pfの波形(図11)
上の220pfをはずした物です。
![]() |
図11.信号1→0のチェック 容量負荷470pfの波形 |
おまけ。。。
LEDを+5VからPORTB1に直結(PORTB吸い込み)した場合の波形
抵抗ぐらい入れないとまずいと思いますけど、試しにやってみると
やはり電圧が落ちきらずに、次のBCF PORTB,2で書きかわってしまっています。
容量負荷は50pまでという規格になっている様ですが、今回の範囲では
十分クリアしていると思います。
ただ、この辺りを無視して過負荷にすると落とし穴が待っている事も
確実な様です。(私は容量なんぞ気にした試しがないし。。。^_^;)
あと、借り物で慣れていないとは言え、デジタルカメラでオシロの
画面をとるのって、難しいと実感しました。。。(^_^;
高山
![]() |
![]() |
![]() |